<?php

namespace App\Services;
/**
 * Created by PhpStorm.
 * User: SCF
 * Date: 2018/10/15
 * Time: 14:30
 */

use App\Models\ActiveApply;
use App\Models\Money;
use App\Models\MoneyDeposit;
use App\Models\MoneyWithdraw;
use App\Models\Order;
use App\Models\UserBank;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use App\Models\UserProperty;
use common\utils\RedisKeys;
use common\utils\SysCode;
use App\Models\UserLevel;
use App\Models\ActiveRecord;
use Illuminate\Support\Facades\Redis;


class WithdrawService
{

    //跳转提款页面获取提款钱包详情
    public static function getWalletInfo($userId)
    {
        $primaryMoney = Money::where(['user_id' => $userId])->first();
        if (empty($primaryMoney)) {
            return error_exit(SysCode::BANK_WITHDRAW_PRAMARY_MOENY_MISS);
        }
        return ['balance' => $primaryMoney['balance']];
    }

    public static function getNoFeeTime($userId)
    {
        $time = date("Y-m-d H:i:s");
        //获取上次出款记录
        $lastWithdraw = MoneyWithdraw::where(['user_id' => $userId])->where('confirm_time', '<=', $time)->select(['confirm_time', 'created_at as apply_time'])->orderBy('confirm_time', 'desc')->first();

        $today_times = 1;
        $date_from = null;
        if (!empty($lastWithdraw)) {
            $date_from = $lastWithdraw['confirm_time'];
            if (strtotime($date_from) >= strtotime(date("Y-m-d H:i:s", strtotime($time)))) {
                $today_times = static::getTodayTime($userId, $time);
                $today_times += 1;
            }
        }
        $levelInfo = User::where(['id' => $userId])->first();
        $userLevelConfig = UserLevel::where(['id' => $levelInfo['level_id']])->first();
        //手续费
        $todayFee = $today_times <= $userLevelConfig['withdraw_daily_times_nofee_limit'] ? 0 : $userLevelConfig['withdraw_fee'];

        $noFeeTime = $userLevelConfig['withdraw_daily_times_nofee_limit'] - $todayFee;
        return [
            'no_fee_tims' => $noFeeTime < 0 ? 0 : $noFeeTime,
            'min' => $userLevelConfig['withdraw_min_limit'],
            'max' => $userLevelConfig['withdraw_max_limit']
        ];
    }

    //判断是否有已申请的订单
    public static function checkExitWithdrawOrder($userId)
    {
        $where = [
            ['user_id', '=', $userId],
            ['status', '=', 0],
        ];
        $checkData = MoneyWithdraw::where($where)->first();
        return $checkData;
    }

    //银行卡列表
    public static function cardList($userId)
    {
        $bankList = UserBank::where(['user_id' => $userId])->select(['a.id', 'b.code', 'b.h5_logo', 'b.name', 'a.address'])->from("user_bank as a")
            ->leftJoin('bank as b', 'b.id', '=', 'a.bank_id')
            ->where('a.status', '=', 1)
            ->get();
        return $bankList;
    }

    //检测是否为第一次提款
    public static function checkFirstWithdraw($userId)
    {
        $checkData = MoneyWithdraw::where(['user_id' => $userId])->where(['status' => 2])->first();
        return $checkData;
    }

    //获取层级信息
    public static function getLevelConfig($userId)
    {
        $userLevel = User::where(['id' => $userId])->first();
        $levelConfig = UserLevel::where(['id' => $userLevel['level_id']])->first();
        return $levelConfig;
    }

    //获取提款时候的手续费信息
    public static function getwithDrawFee($userId, $money = 0)
    {
        $time = date("Y-m-d H:i:s");
        //获取上次出款记录
        $lastWithdraw = MoneyWithdraw::where(['user_id' => $userId])->where('confirm_time', '<=', $time)->select(['confirm_time', 'created_at as apply_time'])->orderBy('confirm_time', 'desc')->first();

        $today_times = 1;
        $date_from = null;
        if (!empty($lastWithdraw)) {
            $date_from = $lastWithdraw['confirm_time'];
            if (strtotime($date_from) >= strtotime(date("Y-m-d H:i:s", strtotime($time)))) {
                $today_times = static::getTodayTime($userId, $time);
                $today_times += 1;
            }
        }

        //获取最近一次稽核的时间
        $date_from = static::getNocheckDate($userId, $date_from);


        //获取稽核数据
        $data = static::getCheckList($userId, $date_from, $time, $money, $today_times);
        $levelConfig = $data['level_config'];

        return [
            'coupon' => $data['total_coupon'],
            'date_from' => $date_from,
            'admin_fee' => $data['total_admin_fee'],
            'each_min_out' => $levelConfig['withdraw_min_limit'],
            'each_max_out' => $levelConfig['withdraw_max_limit'],
            'day_out_times' => $levelConfig['withdraw_daily_times_limit'],
            'day_out_times_nofee' => $levelConfig['day_out_times_nofee'],
            'withdraw_fee' => $data['total_fee'],
            'withdraw_times' => $today_times,
            'list' => $data['list']
        ];
    }

    /**
     * 获取稽核信息
     * @param $userId int 用户id
     * @param $date_from string 稽核开始时间
     * @param $date_to string 结合结束时间
     * @param $money  int 稽核金额
     * @param $today_times int 今天提款次数
     * @param $withdrawFee int 手续费金额
     * @param $page int 页码
     * @param $pageSize int 每页条数
     * @return mixed
     */
    public static function getCheckList($userId, $date_from, $date_to, $money, $today_times, $withdrawFee = 0, $page = null, $pageSize = null)
    {
        $user = User::where(['id' => $userId])->first();
        $userLevelConfig = UserLevel::where(['id' => $user['level_id']])->first();
        //手续费
        $todayFee = $today_times <= $userLevelConfig['withdraw_daily_times_nofee_limit'] ? 0 : $userLevelConfig['withdraw_fee'];
        if (!empty($withdrawFee)) {
            $todayFee = $withdrawFee;
        }
        $checkDataAll = [];
        //获取用户时间端内的入款信息
        $whereWithdraw = [
            ['created_at', '<', $date_to],
            ['created_at', '>=', $date_from],
            ['user_id', '=', $userId],
            ['status', '=', 1],
            ['offline_pay_type', '<=', 12]//不包含补发奖金和补扣金额
        ];

        //手动增加余额,存款数据,手动发送优惠,手动发送返水
        $withSelect = ['amount as money', 'coupon_amount as coupon', 'user_id', 'recharge_time as date', 'withdraw_validbet', 'is_online', 'coupon_validbet'];
        $withDrawData = MoneyDeposit::select($withSelect)->where($whereWithdraw)->orderBy('recharge_time', 'desc')->get()->toArray();
        if (!empty($withDrawData)) {
            $checkDataAll = array_merge($checkDataAll, $withDrawData);
        }


        //活动列表
        $whereActiveApply = [
            ['created_at', '<', $date_to],
            ['created_at', '>=', $date_from],
            ['user_id', '=', $userId],
            ['status', '=', 1],
        ];
        $activeSelect = ['deposit_amount as money', 'coupon_amount as coupon', 'user_id', 'updated_at as date', 'withdraw_require as withdraw_validbet'];
        $activeApplyData = ActiveApply::where($whereActiveApply)->select($activeSelect)->orderBy('created_at', 'desc')->get()->toArray();

        if (!empty($activeApplyData)) {
            $checkDataAll = array_merge($checkDataAll, $activeApplyData);
        }


        //返水表
        $whereRebet = [
            ['created_at', '<', $date_to],
            ['created_at', '>=', $date_from],
            ['user_id', '=', $userId],
            ['status', '=', 1],
        ];
        $rebetSelect = ['amount as coupon', 'user_id', 'created_at as date'];
        $rebetData = ActiveRecord::where($whereRebet)->orderBy('created_at', 'desc')->select($rebetSelect)->get()->toArray();
        if (!empty($rebetData)) {
            $checkDataAll = array_merge($checkDataAll, $rebetData);
        }
        array_multisort(array_column($checkDataAll, 'date'), SORT_DESC, $checkDataAll);

        if (empty($checkDataAll)) {
            return [
                'total_fee' => (int)$todayFee,//手续费
                'total_page' => 0,
                'total_admin_fee' => 0,//行政费
                'total_coupon' => 0,//扣除优惠金额
                'list' => [],//稽核存款列表
                'level_config' => $userLevelConfig,//会员等级信息
            ];
        }
        //获取有效投注金额
        $validBets = static::validBets($userId, $date_from, $date_to);
        $totalAdminFee = $totalCoupon = 0;

        $totalPage = count($checkDataAll);
        $count = $totalPage - 1;
        $endtime = "";
//        return $checkDataAll;

        foreach ($checkDataAll as $idx => &$account) {
            $endtime = empty($endtime) ? date("Y-m-d H:i:s", time()) : $endtime;
            //计算当前的用户充值金额
            $where = [
                ['status', '=', 1],
                ['user_id', '=', $userId],
                ['created_at', '<=', $account['date']]
            ];
            $his_deposit_money = MoneyDeposit::select(DB::raw('sum(amount) as money'))->where($where)->first();
            $his_withdraw_money = MoneyWithdraw::select(DB::raw('sum(amount) as money'))->where($where)->first();
            $whereOrder = [
                ['user_id', '=', $userId],
                ['created_at', '<=', $account['date']]
            ];
            $his_order_money = Order::select(DB::raw('sum(validbet) as valid_bet,sum(profit) as win_earn'))->where($whereOrder)->whereIn('status', [1, 2, 3])->first();
            $account['history_deposit'] = $his_deposit_money['money'];
            $account['history_withdraw'] = $his_withdraw_money['money'];
            $account['history_validbet'] = $his_order_money['valid_bet'];
            $account['history_loseEarn'] = $his_order_money['win_earn'];

            $first = $idx == 0;
            $endDate = $first ? $date_to : $checkDataAll[$idx - 1]['date'];

            //获取有效投注
            $validBet = self::sumValidBet($account['date'], $endDate, $validBets);
            $account['valid_bet'] = $validBet;
            $account['valid_bet_detail'] = static::validBetDetail($account['date'], $endDate, $validBets);

            //存款金额
            $deposit_money = isset($account['money']) ? $account['money'] : 0;
            $account['deposit'] = isset($account['money']) ? $account['money'] : 0;
            //优惠金额
            $coupon = $account['coupon'];
            //todo提款需求目前是直接获取数据库
            $withdrawBet = isset($account['withdraw_validbet']) ? $account['withdraw_validbet'] : 0;
            //除了第一条数据，其他的打码量 = 上次结余的打码量 + 本次的打码量
            $auditValidBet = $first ? $validBet : (isset($account['overplus']) ? $account['overplus'] : 0) + $validBet;

            $is_online = (isset($account['is_online']) && $account['is_online'] == 0) ? 0 : 1;
            if ($deposit_money > 0 && $coupon >= 0) {
                $detail = static::withdrawBetDetail($withdrawBet, $deposit_money, $userLevelConfig, $is_online);
                $account['withdraw_bet_coupon'] = isset($account['coupon_validbet']) ? $account['coupon_validbet'] : $withdrawBet;
                $account['withdraw_bet_principal'] = $detail['principal'];
                $withdrawBet2 = max($detail['principal'], $account['withdraw_bet_coupon']);
                $diff = $auditValidBet - $withdrawBet2;
            } else {
                $account['withdraw_bet_coupon'] = $withdrawBet;
                $account['withdraw_bet_principal'] = $account['withdraw_bet_coupon'] = '';
                $diff = $auditValidBet - $withdrawBet;
            }

            $pass = $diff >= 0;
            if (!$pass) {
                if ($deposit_money > 0 && $coupon >= 0) {
                    //实际打码量 大于等于  本金所需的打码量   不用扣本金的行政费  反之要扣
                    //实际打码量 大于等于   优惠所需打码量    不用扣优惠    反之要扣
//                    return [$deposit_money,$account,$auditValidBet,$account['withdraw_bet_coupon'],$withdrawBet];
                    $couponFee = $validBet >= $account['withdraw_bet_coupon'] ? 0 : $coupon;
//                    return [$auditValidBet,$withdrawBet];
                    if ($auditValidBet < $withdrawBet) {
                        $adminFee = (int)($deposit_money * $userLevelConfig['withdraw_expenese_rate'] / 100);
                        $adminFee > $userLevelConfig['withdraw_expenese_max_limit'] && $adminFee = (int)$userLevelConfig['withdraw_expenese_max_limit'];
                    } else {
                        $adminFee = 0;
                    }
                    $fee = ['coupon' => $couponFee, 'admin_fee' => $adminFee];
                } else {
                    /**
                     * 计算方法： （存款）打码量>存款金额：扣优惠，打码量<存款金额：扣优惠 + 行政费
                     * 计算方法修改：
                     * 只有存款  （存款）打码量 > 有效注单金额   行政费
                     * 只有优惠  （存款）打码量 > 有效注单金额   扣优惠
                     * 存款 + 优惠  （存款）打码量 > 有效注单金额   扣优惠 + 行政费
                     */
                    if ($deposit_money > 0 && $withdrawBet > $auditValidBet) {
                        $adminFee = $deposit_money * $userLevelConfig['withdraw_expenese_rate'] / 100;
                        $adminFee > $userLevelConfig['withdraw_expenese_max_limit'] && $adminFee = $userLevelConfig['withdraw_expenese_max_limit'];
                        $adminFee = (int)$adminFee;
                    } elseif ($money <= 0) {
                        $adminFee = 0;
                    }
                    $fee = ['coupon' => (int)$coupon, 'admin_fee' => $adminFee];
                }
            }
            $account['is_pass'] = $pass;
            //扣除的优惠
            $account['deduct_coupon'] = $pass ? 0 : $fee['coupon'];
            //
            $account['deduct_admin_fee'] = $pass ? 0 : $fee['admin_fee'];

            if ($idx < $count) {
                //本次稽核通过， 把剩余的打码量加到下次的稽核里
                $checkDataAll[$idx + 1]['overplus'] = $pass ? $diff : 0;//($first ? 0 : $account['overplus']);
            }
            $totalAdminFee += $account['deduct_admin_fee'];
            $totalCoupon += $account['deduct_coupon'];
            $account['start_time'] = $account['date'];
            $account['end_time'] = $endtime;
            $account['money'] = isset($account['money']) ? $account['money'] : 0;

            unset($account['level_config']);
            $endtime = $account['date'];
        }
        if ($page) {
            $idx = ($page - 1) * $pageSize;
            $checkDataAll = array_slice($checkDataAll, $idx, $pageSize);
        }

        return [
            'total_fee' => (int)$todayFee,//手续费
            'total_page' => $totalCoupon,
            'total_admin_fee' => (int)$totalAdminFee,//行政费
            'total_coupon' => (int)$totalCoupon,//扣除优惠金额
            'list' => $checkDataAll,//稽核存款列表
            'level_config' => $userLevelConfig,//会员等级信息
        ];
    }

    //折分打码量。 存款记录，并且优惠金额大于的时候才调用此方法
    public static function withdrawBetDetail($withdrawBet, $money, $levelConfig, $depositType)
    {
        $rate = $depositType == 1 ? $levelConfig['deposit_online_validbet_multi'] : $levelConfig['deposit_offline_validbet_multi'];
        $principal = $money * $rate;
        $coupon = $withdrawBet - $principal;
        return ['principal' => $principal, 'coupon' => $coupon];
    }


    //获取有效投注详情
    public static function validBetDetail($start_date, $end_date, $validBets)
    {
        $data = [
            ['name' => '电子', 'valid_bet' => 0],
            ['name' => '视讯', 'valid_bet' => 0],
            ['name' => '体育', 'valid_bet' => 0],
            ['name' => '电竞', 'valid_bet' => 0],
            ['name' => '彩票', 'valid_bet' => 0],
            ['name' => '棋牌', 'valid_bet' => 0],
        ];
        foreach ($validBets as $order) {
            if ($order['created'] <= $start_date || $order['created'] >= $end_date) {
                continue;
            }
            $type = $order['order_type'];
            switch ($type) {
                case 1:
                    $data[0]['valid_bet'] += $order['valid_bet'];
                    break;
                case 2:
                    $data[1]['valid_bet'] += $order['valid_bet'];
                    break;
                case 3:
                    $data[2]['valid_bet'] += $order['valid_bet'];
                    break;
                case 4:
                    $data[3]['valid_bet'] += $order['valid_bet'];
                    break;
                case 5:
                    $data[4]['valid_bet'] += $order['valid_bet'];
                    break;
                case 6:
                    $data[4]['valid_bet'] += $order['valid_bet'];
                    break;
                default:
                    ;
                    break;
            }
        }
        return array_values($data);
    }


    /**
     * 获取时间段内的有效投注
     *
     * @param string $start_date
     * @param string $end_date
     * @param array $orders
     * @return int
     */
    private static function sumValidBet($start_date, $end_date, $orders)
    {
        $sum = 0;
        foreach ($orders as $order) {
            if ($order['created'] <= $start_date || $order['created'] >= $end_date) {
                continue;
            }

            $sum += $order['valid_bet'];
        }

        return round($sum, 0);
    }

    //获取对应有效投注金额
    public static function validBets($userId, $date_from, $date_to)
    {
        //系统稽核数据
        $betConfig = Redis::get(RedisKeys::SET_GLOBAL);
        $betConfig = json_decode($betConfig, true);
        if (isset($betConfig['base']['valid_bet_percent'])) {
            $config = $betConfig['base']['valid_bet_percent'];
        } else {
            $config = [];
        }
        $whereBet = [
            ['bet_time', '>=', $date_from],
            ['bet_time', '<=', $date_to],
            ['user_id', '=', $userId],
            ['status', '=', 2],
        ];
        $select = ['game_type as order_type', 'validbet as valid_bet', 'bet_time as created', 'user_id'];
        $bet = Order::where($whereBet)->select($select)->get()->toArray();
        if ($bet) {
            foreach ($bet as &$order) {
                switch ($order['order_type']) {
                    case 1:
                        $field = 'egame';
                        break;
                    case 2:
                        $field = 'live';
                        break;
                    case 3:
                        $field = 'sport';
                        break;
                    case 4:
                        $field = 'esport';
                        break;
                    case 5:
                        $field = 'lottery';
                        break;
                    case 6:
                        $field = 'card';
                        break;
                }

                $percent = isset($config[$field]) ? $config[$field] : 100;
                $money = round($order['valid_bet'] * ($percent ?? 100) / 100, 2);
                $order['valid_bet'] = $money;
            }

        }
        return $bet;
    }

    //获取最后一个免稽核时间
    public static function getNocheckDate($userId, $dateFrom)
    {
        $nocheckTime = UserProperty::where(['user_id' => $userId])->first();
        $checktime = $nocheckTime['nocheck_time']->format("Y-m-d H:i:s");
        if (!empty($nocheckTime)) {
            $checktime > $dateFrom && $dateFrom = $checktime;
        }
        return $dateFrom;
    }

    //获取0点到当前时间次数
    public static function getTodayTime($userId, $date)
    {
        $date_from = date('Y-m-d 00:00:00', strtotime($date));//当天0点起算
        $where = [
            ['user_id', '=', $userId],
            ['status', '=', 'paid'],
            ['created_at', '>=', $date_from],
            ['created_at', '<=', $date]
        ];
        $data = MoneyWithdraw::where($where)->count();
        return $data;
    }


    //获取会员取款列表
    public static function getWithDrawList($select = "*", $where = [], $time = "")
    {
        if (empty($time)) {
            $time = date("Y-m-d H:i:s");
        }
    }

    //获取用户资料信息
    public static function getProperty($user_id)
    {
        $data = user::where(['id' => $user_id])->first();
        return $data;
    }
}
